#include "spacecol3d.h"


SpaceCol3D::SpaceCol3D(Renderer *render)
{
    BPR = BPR3D;
    BPRSQ = BPR*BPR;
    numBlock = BPRSQ*BPR;
   // m_blocks = new Block[numBlock];
    m_renderer = render;
    blockSize = PLANE_SIZE/BPR;
    this->ROH = 1.0;
    m_renderer = render;
    this->R = 6.0;
    //numBuds = 0;

}

SpaceCol3D::~SpaceCol3D()
{
     //if (m_tree) m_tree->freeTree(m_tree->treeRoot);
     //delete[] m_blocks;
     //m_blocks = NULL;

}

void SpaceCol3D::updateTree(TreeGen3D *newTree)
{
    if (m_tree) m_tree->freeTree(m_tree->treeRoot);
    (m_tree) = newTree;
}

void SpaceCol3D::clearTree(){
    delete m_tree;
   // m_tree = new TreeGen3D();
   //( (TreeGen3D *)m_tree)->genTree(float2(100,100));

    delete[] m_blocks;

}

// generate markers
void SpaceCol3D::generateMarkers()
{
    double size = (double) PLANE_SIZE/BPR;

    for (int i = 0; i < numBlock; i++)
    {
        Block * currentBlock = &m_blocks[i];
        currentBlock->depth = i / BPRSQ;
        int index2d = i % BPRSQ;
        currentBlock->col = (int) index2d % BPR;
        currentBlock->row = (int) index2d / BPR;
        currentBlock->updateSize(size, float3 (currentBlock->col * size, currentBlock->row * size, currentBlock->depth*size));
        for (int j = 0; j < currentBlock->numMarkers; j++)
        {
            double random = ((double) rand()) / (double) RAND_MAX;
            currentBlock->m_markers.push_back( (random*size) + currentBlock->startCoord.x); // x coord

            double random2 = ((double) rand()) / (double) RAND_MAX;
            double range2 = size;
            currentBlock->m_markers.push_back((random2*size) + currentBlock->startCoord.y); // y coord

            double random3 = ((double) rand()) / (double) RAND_MAX;
            currentBlock->m_markers.push_back((random3*size) + currentBlock->startCoord.z); // y coord

            currentBlock->m_markers.push_back( -1); // does not belong to any bud;
            currentBlock->m_markers.push_back( -1); // no distance calculated yet;
            /*if (currentBlock->m_markers.at(j*5 + 0) < 0 || currentBlock->m_markers.at(j*5 + 1) < 0)
            {
                cout << "smaller than 0:" << currentBlock->col << "//" << currentBlock->row << endl;
               // cout << "value:" << currentBlock->m_markers[j*5 + 0] << "//" << currentBlock->m_markers[j*5 + 1] << endl;
                cout << "random:" << random << "//" << random2 << endl;
                cout << "range:" << range << "//" << range2 << endl;
                cout << "startCoord:" << currentBlock->startCoord << endl;
                cout << "size:" << size << endl;
                cout << endl;
            }*/
        }
    }
}

// draw markers, for debugging purpose.
void SpaceCol3D::drawMarkers()
{
    GLUquadric * mQuadric = gluNewQuadric();
    for (int k = 0; k < numBlock; k++)
    {
        Block * currentBlock = &m_blocks[k];
        for (int j = 0; j < currentBlock->m_markers.size()/5.0; j++)
        {
            if(currentBlock->m_markers.at(j*5 +3)> -1.9 && currentBlock->m_markers.at(j*5 +4)>-1.9)
            {
                glColor3f(0, 0.0, 1.0);
                glPushMatrix();
                glTranslatef(currentBlock->m_markers.at(j*5 + 0), currentBlock->m_markers.at(j*5 + 1),currentBlock->m_markers.at(j*5 + 2));
               /* glBegin(GL_QUADS);
                    glVertex3f(-.5,-.5,0);
                    glVertex3f(.5,-.5,0);
                    glVertex3f(.5,.5,0);
                    glVertex3f(-.5,.5,0);
                glEnd();*/
                //gluDisk(mQuadric, 0, 2.0/2.0, 10, 10);
                gluSphere(mQuadric,2.0,10,10);
                glPopMatrix();
            }

        }
    }
}
// create a tree root
void SpaceCol3D::initialize(float2 position)
{
    m_tree = new TreeGen3D(m_renderer);
    ((TreeGen3D *)m_tree)->genTree(position);
}

void SpaceCol3D::addMarkers(double x, double y, double z)
{
    //is this right??
    double size = PLANE_SIZE/BPR;
    int col = (int)x/size;
    int row = (int)y/size;
    int depth = (int)z/size;
    int index = depth*BPRSQ +  row*BPR + col;
    if(x> PLANE_SIZE || y> PLANE_SIZE  || z> PLANE_SIZE){
        cout<<"indexing too high, returning"<<endl;
        return;
    }
    else if(x<0 || y<0 || z<0){
        cout<<"indexing too low, returning"<<endl;
        return;
    }
    m_blocks[index].m_markers.push_back(x);
    m_blocks[index].m_markers.push_back(y);
    m_blocks[index].m_markers.push_back(z);
    m_blocks[index].m_markers.push_back(-1);
    m_blocks[index].m_markers.push_back(-1);
}

